package cn.fcq.basic.service.impl;

import cn.fcq.basic.constants.BaseConstant;
import cn.fcq.basic.dto.RegisterDto;
import cn.fcq.basic.exception.BusinessException;
import cn.fcq.basic.service.IVerifyCodeService;
import cn.fcq.basic.util.SmsUtils;
import cn.fcq.basic.util.StrUtils;
import cn.fcq.basic.util.VerifyCodeUtils;
import cn.fcq.user.domain.User;
import cn.fcq.user.mapper.UserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.xml.crypto.Data;
import java.util.concurrent.TimeUnit;

@Service
public class VerifyCodeServiceImpl implements IVerifyCodeService {
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private UserMapper userMapper;
    @Override
    public String imageCode(String key) {
        if (!StringUtils.hasLength(key)){
            throw new BusinessException("key不能为空啊！");
        }
//        (每次都是直接生成新的，但是要覆盖前面的)
//        。生成code = 9527
        String code = StrUtils.getComplexRandomString(4);
//        。保存redis，设置过期时间  key是什么==前端请求给我传递的UUID
        redisTemplate.opsForValue().set(key,code,5, TimeUnit.MINUTES);
//        。使用2D引擎把code画成图
//        。把图使用Base64编码成字符串
//        。返回Base64编码的字符串
        return VerifyCodeUtils.VerifyCode(100,40,code);
    }

    /**
     * 发送短信验证
     * @param dto
     */
    @Override
    public void smsCode(RegisterDto dto) {
        //一：校验
        String phone = dto.getPhone();
        String imageCodeKey = dto.getImageCodeKey();
        String imageCodeValue = dto.getImageCodeValue();
        //1：空校验
        if (StringUtils.isEmpty(phone)||
            StringUtils.isEmpty(imageCodeKey)||
                StringUtils.isEmpty(imageCodeValue)
        ){
            throw new BusinessException("参数不能为空哦！");
        }
        //2：图形验证码校验，根据前端传递过来的imageCodeKey从redis中获取图形验证码。
        Object imageCodeTmp = redisTemplate.opsForValue().get(imageCodeKey);
        //2.1：获取不到，图形验证码过期，重新获取
        if (imageCodeTmp==null){
            throw new BusinessException("图形验证码已失效，请重新获取");
        }
        //2.2：获取到了，比对图形验证码是否正确
        // 不要区分大小写
        if(!imageCodeTmp.toString().equalsIgnoreCase(imageCodeValue)){
            //不正确，提示图形验证码有误
            throw new BusinessException("验证码错误，请重新输入");
        }
        //正确，继续注册步骤
        //3：校验手机是否注册过
        User userTmp =userMapper.loadByPhone(phone);
        //3.1：注册过了，提示直接去登录
        if (userTmp!=null){
            throw new BusinessException("该用户已注册，请直接登录");
        }
        //3.2：没有，继续注册
        //二：短信验证：
        //1.	根据手机号拼接key，139:register, 去redis获取曾经可能发送过的验证码
        String key = BaseConstant.RegisterConstants.REGISTER_SMS_PREFIX + phone;
        Object smsCodeTmp = redisTemplate.opsForValue().get(key);
        //1.1获取到了
        String smsCode="";
        if (smsCodeTmp!=null){
            //A．校验是否过了一分钟重发时间。验证码：当前时间戳
            Long oldTmp = Long.valueOf(smsCodeTmp.toString().split(":")[1]);
            //        <1分钟，爬远点
            if(System.currentTimeMillis()-oldTmp<=1*60*1000){
                throw new BusinessException("请耐心等待");
            }
            //        >1分钟，（<3分钟，验证码还有效），继续使用还没过期的验证码，刷新过期时间
            smsCode = smsCodeTmp.toString().split(":")[0];
        }else {
            //1.2没获取到
            //        生成新的短信验证码
            smsCode= StrUtils.getComplexRandomString(4);
        }
        //2.	将存储的redis设置一个过期时间
        String smsCodeValue = smsCode + ":" + System.currentTimeMillis();
        redisTemplate.opsForValue().set(key,
                smsCodeValue,
                3,
                TimeUnit.MINUTES);
        //3.	发送短信
        //SmsUtils.sendSms(phone,"您的验证码是:"+smsCode+"请在3分钟内输入验证码");
        System.out.println("您的验证码是:"+smsCode+"请在3分钟内输入验证码");
    }
}
